package edu.scsu.csci.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import edu.scsu.csci.IController;
import edu.scsu.csci.config.ConfigurationException;
import edu.scsu.csci.core.ApplicationConfiguration;
import edu.scsu.csci.core.ActionURL;
import edu.scsu.csci.logging.ILogger;

/**
 * <p> This reprsents the core of the fornt controller implemntation adapted by the framework.
 * <p> This acts as point of single entry for all the requests to the application.
 * <p> It creates the delegates to the IContoller implmentation provided to the framework to do
 * 	   the rest of the work. 
 *
 * @author Maqbool Khan
 * @since jdk 1.5
 * @see   edu.scsu.csci.IController
 * @see   edu.scsu.csci.core.ActionURL
 * @viz.diagram FrontControllerServlet.tpx
 */
public class FrontControllerServlet extends HttpServlet{

	/**
	 * serialversion uid
	 */
	private static final long serialVersionUID = 1084551538406918486L;

	/**
	 * controller
	 */
	private IController controller;
	
	/**
	 * web application configuration.
	 */
	private ApplicationConfiguration appConfiguration;

	/**
	 * Initializes the servlet
	 */
	@Override
	public void init() throws ServletException {
		super.init();
		this.appConfiguration = ApplicationConfiguration.getInstance(getServletContext());
		try {
			this.appConfiguration.configure();
			this.controller = IController.ControllerFactory.create(getServletContext());
		}
		catch (ConfigurationException e) {
			throw new ServletException("Cannot configure the webframework.", e);
		}
		catch (IOException e) {
			throw new ServletException("Cannot configure the webframework. " +
					" Please provide the configuartion file.", e);
		}
	}

	@Override
	protected void service(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		ILogger.LoggerFactory.getLogger().debug("new request");
		try {
			String uri = request.getRequestURI();
			ILogger.LoggerFactory.getLogger().debug("Requested url (request wrapped): " + uri);
			uri = uri.substring(uri.lastIndexOf('/') + 1);
			ILogger.LoggerFactory.getLogger().debug("requested uri: " + uri);
			uri = uri.substring(0, uri.lastIndexOf('.'));
						
			int methodPosition = uri.lastIndexOf('.');
			String methodName = uri.substring(methodPosition + 1, uri.length());
			ILogger.LoggerFactory.getLogger().debug("Operation: " + methodName);
			
			String className = uri.substring(0, methodPosition);
			ILogger.LoggerFactory.getLogger().debug("Command: " + className);
			
			ActionURL commandURL = new ActionURL(className, methodName);
			
			WebUtils.setRequest(request);
			WebUtils.setResponse(response);
			WebUtils.setSession(request.getSession(true));
			
			controller.execute(commandURL, request, response);
		}
		catch(Exception e){
			ILogger.LoggerFactory.getLogger().error(e, "Cannot process request");
			throw new ServletException(e);
		}
	}
}
